home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 23
/
Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso
/
Aminet
/
text
/
edit
/
Smartindent.lha
/
Smartindent
/
Source
/
semantics_lisp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-12-14
|
5KB
|
338 lines
/*(( "Kopf" */
/* -----------------------------------------------------------------------------
$Id: semantics_c.c,v 1.5 1997/07/17 00:24:10 mshopf Exp mshopf $
GoldED API client, ©1995 Matthias Hopf.
Compiled with SasC.
Lisp style semantics parser
------------------------------------------------------------------------------
*/
/*)) */
#include "semantics.h"
/*(( "Private prototypes" */
FUNC (OUTSIDEBLOCK);
FUNC (BLOCK);
FUNC (COMMENT);
FUNC (STRING_DOUBLE);
FUNC (STRING_SINGLE);
/*)) */
/*(( "Indent_Lisp ()" */
/****** Main routine ******/
void Indent_Lisp (sc_t *c)
{
OUTSIDEBLOCK (c, 0);
if (c->CurrentLine <= c->EndIndent)
Error (c, UNMATCHED_BRACE_ERROR);
debug (Dbug, ("\n\n")); // Do it always...
}
/*)) */
/*(( "IsWord_Lisp ()" */
int IsWord_Lisp (sc_t *c, char *buf, int len, int maxlen)
{
char *t;
switch (len) {
case 0:
return MATCH_TRUE;
case 1:
switch (buf [0]) {
case ';':
case '\'':
case '"':
case '(':
case ')':
case '\\':
return MATCH_EXACT;
}
return MATCH_TRUE;
}
for (t = buf+1; t < & buf [len]; t++)
if (*t == '\0' || *t == ' ' || *t == '\t' || *t == ';' ||
*t == '(' || *t == ')' || *t == '"' || *t == '\'' || *t == '\\')
return MATCH_FALSE;
return MATCH_TRUE;
}
/*)) */
/*(( "KeyPress_Lisp ()" */
void KeyPress_Lisp (sc_t *c, int key)
{
int Line = c->Edit->Line;
int StartLine = -1, EndLine = -1;
switch (key) {
case ';':
StartLine = EndLine = Line;
break;
case '(':
case ')':
StartLine = EndLine = Line;
break;
case '\n':
case '\15':
StartLine = Line > 0 ? Line-1 : 0;
EndLine = Line;
}
if (StartLine >= 0)
{
InitIndent (c, StartLine, EndLine, MODE_LINE | MODE_CURSOR);
Indent_Lisp (c);
CleanupIndent (c);
}
}
/*)) */
/*(( "Semantics structure" */
/****** Method structure ******/
struct Semantic Lisp_Sem =
{
"Lisp",
"Lisp semantics parser",
"V0.1 ©1995 Matthias Hopf",
IsWord_Lisp,
KeyPress_Lisp,
Indent_Lisp,
{ 1, 9, 9, 9, 1, 4, 40 } /* 9: not used here*/
} ;
/*)) */
/*(( "Parser specific errors" */
static const char *FUNCTION_AFTER_BRACE_EXPECTED_ERROR = "Expecting function invocation after brace in line %ld";
/*))*/
/*(( "OUTSIDEBLOCK ()" */
FUNC (OUTSIDEBLOCK)
{
debug (D_PARSER, ("OUTSIDEBLOCK(%ld)\t", I));
dcheck;
DOGET
{
switch (W[0]) { // no test for length == 1 !
case '(':
UPDATE (I);
c->BlockIndent = C;
CALL (BLOCK, C + CONFIG.Block_Level);
break;
case ')':
Error (c, UNMATCHED_BRACE_ERROR);
return;
case ';':
if (BOL)
{
if (C == 0)
INDENT (0);
else
INDENT (I+CONFIG.Comment_Level);
}
else
INDENT (CONFIG.LineComment_Abs);
CALL (COMMENT, C);
break;
default:
Error (c, SYNTAX_ERROR);
}
}
}
/*))*/
/*(( "BLOCK ()" */
FUNC (BLOCK)
{
int argnr = 0, lastlevel;
debug (D_PARSER, ("BLOCK(%ld)\t", I));
dcheck;
lastlevel = c->BlockIndent;
DOGET
{
PEEK;
if (P[0] == ';')
SETEOL;
switch (W[0]) { // no test for length == 1 !
case '(':
INDENT (I);
switch (argnr++) {
case 0:
case 1:
I = C;
}
c->BlockIndent = C;
CALL (BLOCK, C + CONFIG.Block_Level);
c->BlockIndent = lastlevel;
break;
case ')':
INDENT (lastlevel);
return;
case ';':
if (BOL)
{
if (C == 0)
INDENT (0);
else
INDENT (I+CONFIG.Comment_Level);
}
else
INDENT (CONFIG.LineComment_Abs);
CALL (COMMENT, C);
break;
case '"':
switch (argnr++) {
case 0:
Error (c, FUNCTION_AFTER_BRACE_EXPECTED_ERROR);
break;
case 1:
UPDATE (I);
break;
default:
INDENT (I);
}
CALL (STRING_DOUBLE, C+1);
break;
case '\'':
switch (argnr++) {
case 0:
Error (c, FUNCTION_AFTER_BRACE_EXPECTED_ERROR);
break;
case 1:
UPDATE (I);
break;
default:
INDENT (I);
}
CALL (STRING_SINGLE, C+1);
break;
default:
switch (argnr++) {
case 0:
INDENT (I);
I = N;
break;
case 1:
UPDATE (I);
break;
default:
INDENT (I);
}
}
}
}
/*)) */
/*(( "COMMENT ()" */
FUNC (COMMENT)
{
debug (D_PARSER, ("COMMENT(%ld)\t", I));
dcheck;
GET;
while (*W == ';')
{
I = C;
GET;
}
INDENT (I + 2);
UNGET;
DOGET
{
if (EOL)
return;
}
}
/*)) */
/*(( "STRING_SINGLE ()" */
FUNC (STRING_SINGLE)
{
debug (D_PARSER, ("STRING_SINGLE(%ld)\t", I));
dcheck;
if (EOL)
ERROR (STRING_TERMINATION_ERROR);
DOGET
{
if (W[1] == 0)
{
switch (W[0]) {
case '\'':
return;
case '\\':
GET; /* skip next char (may be ' or \ ) */
}
}
if (EOL)
ERROR (STRING_TERMINATION_ERROR);
}
}
/*)) */
/*(( "STRING_DOUBLE ()" */
FUNC (STRING_DOUBLE)
{
debug (D_PARSER, ("STRING_DOUBLE(%ld)\t", I));
dcheck;
if (EOL)
ERROR (STRING_TERMINATION_ERROR);
DOGET
{
if (W[1] == 0)
{
switch (W[0]) {
case '"':
return;
case '\\':
GET; /* skip next char (may be " or \ ) */
}
}
if (EOL)
ERROR (STRING_TERMINATION_ERROR);
}
}
/*)) */